package wrapper

import (
	"errors"
	"github.com/gin-gonic/gin"
	"sgo/common/constant"
	"sgo/common/response"
	"sgo/error/handler"
	"sgo/scontext"
)

type HandlerFuncWrapper func(ctx *gin.Context, sc *scontext.SgoContext) response.Response

// defer处理panic

func handlePanic(ctx *gin.Context, sc *scontext.SgoContext) {
	if err := recover(); err != nil {
		r := response.Fail()
		switch err.(type) {
		case error:
			sc.Logger.Error(err.(error).Error())
			r = handler.HandleError(sc, err.(error))
		case string:
			sc.Logger.Error(err.(string))
			r = handler.HandleError(sc, errors.New(err.(string)))
		default:
			sc.Logger.Error(constant.SERVER_INNER_ERROR)
			r = response.FailWithMessage(constant.SERVER_INNER_ERROR)
		}
		response.JSON(ctx, r)
	}
}

func HandlerFunc(sc *scontext.SgoContext, wrapper HandlerFuncWrapper) gin.HandlerFunc {
	// 日志处理
	// 异常处理
	// 此处类似Java中的切面
	return func(ctx *gin.Context) {

		defer handlePanic(ctx, sc)

		resp := wrapper(ctx, sc)

		// 统一处理异常
		if resp.Err != nil {
			sc.Logger.Error(resp.Err.Error())
			resp = handler.HandleError(sc, resp.Err)
		}

		response.JSON(ctx, resp)
	}
}
